<?php

class xml_gm_params {

	function xml_gm_params() {
		$this->width = intval(get_option(key_xmlgm_width));
		$this->height = intval(get_option(key_xmlgm_height));
		$this->align = get_option(key_xmlgm_align);
		$this->googleMapsAPIKey = get_option(key_xmlgm_uid);
		$this->viewStyle = get_option(key_xmlgm_viewstyle);
		$this->urlDisplayMode = get_option(key_xmlgm_urldisplaymode);
		$this->panZoomControl = get_option(key_xmlgm_panzoomcontrol);
		$this->overViewMapControl = get_option(key_xmlgm_overviewmap);
		$this->scaleControl = get_option(key_xmlgm_scalecontrol);
		$this->mapTypeControl = get_option(key_xmlgm_maptypecontrol);
		$this->mapNormal = get_option(key_xmlgm_mapnorm);
		$this->mapHybrid = get_option(key_xmlgm_maphyb);
		$this->mapSatellite = get_option(key_xmlgm_mapsat);
		$this->mapPhysical = get_option(key_xmlgm_mapphy);
		$this->mapEarth = get_option(key_xmlgm_mapearth);
		$this->dragging = get_option(key_xmlgm_dragging);
		$this->doubleClickZoom = get_option(key_xmlgm_doubleClickZoom);
		$this->continuousZoom = get_option(key_xmlgm_continuousZoom);
		$this->googleBar = get_option(key_xmlgm_googleBar);
		$this->scrollWheelZoom = get_option(key_xmlgm_scrollWheelZoom);
		$this->measurement = get_option(key_xmlgm_elevationmeasurement);
		$this->speedscale = get_option(key_xmlgm_speedscale);
		$this->cacheDuration = intval(get_option(key_xmlgm_cache));

		$this->kmlParsing = get_option(key_xmlgm_kmlparsing);
			
		$this->gpxLineColor = get_option(key_xmlgm_linecolor);
		$this->gpxLineWidth = intval(get_option(key_xmlgm_linewidth));
		$this->gpxLineOpacity = intval(get_option(key_xmlgm_lineopacity));
		$this->gpxView = get_option(key_xmlgm_gpxview);
		$this->gpxElevationLineColor = str_replace("#","",get_option(key_xmlgm_elevlinecolor));
		$this->gpxElevationChart = get_option(key_xmlgm_elevationchart);
		$this->gpxElevationLineWidth = intval(get_option(key_xmlgm_elelinewidth));
		$this->gpxElevationChartHeight = intval(get_option(key_xmlgm_elevationheight));	
		$this->gpxElevationChartTitle = get_option(key_xmlgm_elevationtitle);
		$this->gpxSpeedLineColor = str_replace("#","",get_option(key_xmlgm_speedlinecolor));
		$this->gpxSpeedChart = get_option(key_xmlgm_speedchart);
		$this->gpxSpeedLineWidth = intval(get_option(key_xmlgm_speedlinewidth));
		$this->gpxSpeedChartHeight = intval(get_option(key_xmlgm_speedheight));
		$this->gpxSpeedChartTitle = get_option(key_xmlgm_speedcharttitle);
		$this->gpxHeartRateLineColor = str_replace("#","",get_option(key_xmlgm_heartratelinecolor));
		$this->gpxHeartRateChart = get_option(key_xmlgm_heartratechart);
		$this->gpxHeartRateLineWidth = intval(get_option(key_xmlgm_heartratelinewidth));
		$this->gpxHeartRateChartHeight = intval(get_option(key_xmlgm_heartrateheight));
		$this->gpxHeartRateChartTitle = get_option(key_xmlgm_heartratecharttitle);		
		$this->gpxCSSStyle = get_option(key_xmlgm_gpxcssstyle);
		$this->gpxCheckpointMarkerColor = get_option(key_xmlgm_checkpointmapmarkercolor);
		$this->gpxCheckpointInterval = get_option(key_xmlgm_checkpointinterval);
		$this->gpxCheckpointTable = get_option(key_xmlgm_checkpointtable);
		$this->gpxCheckpointTableTemplate = get_option(key_xmlgm_checkpointtabletempl);
		$this->gpxCheckpointTableRowTemplate = get_option(key_xmlgm_checkpointtablerowtempl);
		$this->gpxWaypointMarkerTemplate = get_option(key_xmlgm_gpxmarkertempl);
		$this->gpxDirectOpenWPLink = get_option(key_xmlgm_gpxdirectopenwplink);
		$this->nggalMarkerTemplate = get_option(key_xmlgm_nggmarkertempl);

		if (strlen($this->gpxCheckpointTableTemplate)==0) {
			$filename = dirname(__FILE__)."/templates/defaultcptable.template";
			if (file_exists($filename)) {
				$handle = fopen ($filename, "r");
				$this->gpxCheckpointTableTemplate = fread ($handle, filesize ($filename));
				fclose ($handle);
			}
		}
		if (strlen($this->gpxCheckpointTableRowTemplate)==0) {
			$filename = dirname(__FILE__)."/templates/defaultcptablerow.template";
			if (file_exists($filename)) {
				$handle = fopen ($filename, "r");
				$this->gpxCheckpointTableRowTemplate = fread ($handle, filesize ($filename));
				fclose ($handle);
			}
		}
		if (strlen($this->gpxWaypointMarkerTemplate)==0) {
			$filename = dirname(__FILE__)."/templates/defaultgpxmarker.template";
			if (file_exists($filename)) {
				$handle = fopen ($filename, "r");
				$this->gpxWaypointMarkerTemplate = fread ($handle, filesize ($filename));
				fclose ($handle);
			}
		}
		if (strlen($this->nggalMarkerTemplate)==0) {
			$filename = dirname(__FILE__)."/templates/defaultnggmarker.template";
			if (file_exists($filename)) {
				$handle = fopen ($filename, "r");
				$this->nggalMarkerTemplate = fread ($handle, filesize ($filename));
				fclose ($handle);
			}
		}
	}

	var $width = 664;
	var $height = 400;
	var $align = "left";
	var $googleMapsAPIKey = "";
	var $viewStyle = "G_NORMAL_MAP";
	var $urlDisplayMode = "title";
	var $panZoomControl = "large";
	var $overViewMapControl = "hide";
	var $scaleControl = "hide";
	var $mapTypeControl = "show";
	var $mapNormal = "show";
	var $mapHybrid = "show";
	var $mapSatellite = "show";
	var $mapPhysical = "hide";
	var $mapEarth = "hide";
	var $dragging = "enabled";
	var $doubleClickZoom = "enabled";
	var $continuousZoom = "enabled";
	var $googleBar = "disabled";
	var $scrollWheelZoom = "enabled";
	var $kmlParsing = "enabled";
	var $cacheDuration = -1;

	var $manualZoom = 0;
	var $minLat = 0;
	var $maxLat = 0;
	var $minLon = 0;
	var $maxLon = 0;
	var $zoom = 0;
	var $deltazoom = 0;

	var $gpxLineColor = "#0000FF";
	var $gpxLineWidth = 5;
	var $gpxLineOpacity = 50;
	var $gpxView = "all";
	var $gpxInterval = 1;
	var $gpxElevationLineColor = "0000FF";
	var $gpxElevationLineWidth = 5;
	var $gpxElevationChart = "show";
	var $gpxElevationChartHeight = 200;
	var $measurement = "metric";
	var $speedscale = "level2";
	var $gpxSpeedLineColor = "0000FF";
	var $gpxSpeedLineWidth = 5;
	var $gpxSpeedChart = "hide";
	var $gpxSpeedChartHeight = 200;
	var $gpxHeartRateLineColor = "0000FF";
	var $gpxHeartRateLineWidth = 5;
	var $gpxHeartRateChart = "hide";
	var $gpxHeartRateChartHeight = 200;
	var $gpxHeartRateChartTitle = "Heart Rate Profile";
	var $gpxCSSStyle = "font-family: Verdana, Arial, Sans-Serif;";
	var $gpxSpeedChartTitle = "Speed Profile";
	var $gpxElevationChartTitle = "Elevation Profile";
	var $gpxCheckpointInterval = 0;
	var $gpxCheckpointMarkerColor = "red";
	var $gpxCheckpointTable = "hide";
	var $gpxDirectOpenWPLink = "dblclick";

	var $gpxCheckpointTableTemplate = "";
	var $gpxCheckpointTableRowTemplate = "";
	var $gpxWaypointMarkerTemplate = "";
	var $nggalMarkerTemplate = "";

	var $nggalGalleries = array();
	var $nggalPics = array();

	function getNggCount() {
		return count($this->nggalGalleries) + count($this->nggalPics);
	}

	function printObjectHTMLComment() {
		print_r("<!-- Debug Info Actual Parameter Object \n");
		print_r($this);
		print_r("\n -->");
	}

	function setParams($param_string) {
		$param_string = str_replace("####nnnn####","",$param_string);
		$param_string = str_replace("####rrrr####","",$param_string);
		$manualzoom = 0;
		$vars = split(";",$param_string);
		for ($i=0 ;$i<count($vars);$i++) {
			$varvalue=split("=",$vars[$i]);
			if (count($varvalue)==2) {
				$varvalue[0] = trim($varvalue[0]);
				$varvalue[1] = trim($varvalue[1]);
				switch (strtolower($varvalue[0])) {
					case "kmlparsing":
						$this->kmlParsing = $varvalue[1];
						break;
					case "ngg_gallery":
						if (is_numeric($varvalue[1])) {
							$this->nggalGalleries[] = intval($varvalue[1]);
						}
						break;
					case "ngg_picture":
						if (is_numeric($varvalue[1])) {
							$this->nggalPics[] = intval($varvalue[1]);
						}
						break;
					case "dragging":
						$this->dragging = $varvalue[1];
						break;
					case "doubleclickzoom":
						$this->doubleClickZoom = $varvalue[1];
						break;
					case "continuouszoom":
						$this->continuousZoom = $varvalue[1];
						break;
					case "googlebar":
						$this->googleBar = $varvalue[1];
						break;
					case "scrollwheelzoom":
						$this->scrollWheelZoom = $varvalue[1];
						break;
					case "urldisplaymode":
						$this->urlDisplayMode = $varvalue[1];
						break;
					case "maptype":
						$this->viewStyle = $varvalue[1];
						break;
					case "width":
						if (is_numeric($varvalue[1])) {
							$this->width = intval($varvalue[1]);
						}
						break;
					case "height":
						if (is_numeric($varvalue[1])) {
							$this->height = intval($varvalue[1]);
						}
						break;
					case "cache":
						if (is_numeric($varvalue[1])) {
							$this->cacheDuration = intval($varvalue[1]);
						}
						break;						
					case "align":
						$this->align = $varvalue[1];
						break;
					case "panzoomcontrol":
						$this->panZoomControl = $varvalue[1];
						break;
					case "overviewmapcontrol":
						$this->overViewMapControl = $varvalue[1];
						break;
					case "scalecontrol":
						$this->scaleControl = $varvalue[1];
						break;
					case "maptypecontrol":
						$this->mapTypeControl = $varvalue[1];
						break;
					case "mapnormal":
						$this->mapNormal = $varvalue[1];
						break;
					case "maphybrid":
						$this->mapHybrid = $varvalue[1];
						break;
					case "mapsat":
						$this->mapSatellite = $varvalue[1];
						break;
					case "mapearth":
						$this->mapEarth = $varvalue[1];
						break;
					case "mapphysical":
						$this->mapPhysical = $varvalue[1];
						break;
					case "gpxinterval":
						if (is_numeric($varvalue[1])) {
							$this->gpxInterval = intval($varvalue[1]);
						}
						break;
					case "gpxcheckpointtable":
						$this->gpxCheckpointTable = $varvalue[1];
						break;
					case "gpxcolor":
						$this->gpxLineColor = myFunctions::colorName2Hex($varvalue[1]);
						break;
					case "gpxelevationcolor":
						$this->gpxElevationLineColor = str_replace("#","",myFunctions::colorName2Hex($varvalue[1]));
						break;
					case "gpxelevation":
						$this->gpxElevationChart = $varvalue[1];
						break;
					case "gpxelevationmeasurement":
					case "measurement":
						$this->measurement = $varvalue[1];
						break;
					case "speedscale":
						$this->speedscale = $varvalue[1];
						break;
					case "gpxspeedchartcolor":
						$this->gpxSpeedLineColor = str_replace("#","",myFunctions::colorName2Hex($varvalue[1]));
						break;
					case "gpxspeedchart":
						$this->gpxSpeedChart = $varvalue[1];
						break;
					case "gpxheartratechartcolor":
						$this->gpxHeartRateLineColor = str_replace("#","",myFunctions::colorName2Hex($varvalue[1]));
						break;
					case "gpxheartratechart":
						$this->gpxHeartRateChart = $varvalue[1];
						break;
					case "gpxlinewidth":
						if (is_numeric($varvalue[1])) {
							$this->gpxLineWidth = intval($varvalue[1]);
						}
						break;
					case "gpxelevationlinewidth":
						if (is_numeric($varvalue[1])) {
							$this->gpxElevationLineWidth = intval($varvalue[1]);
						}
						break;
					case "gpxelevationheight":
						if (is_numeric($varvalue[1])) {
							$this->gpxElevationChartHeight = intval($varvalue[1]);
						}
						break;
					case "gpxcheckpointinterval":
						if (is_numeric($varvalue[1])) {
							$this->gpxCheckpointInterval = floatval($varvalue[1]);
						}
						break;
					case "gpxcheckpointmarkercolor":
						$this->gpxCheckpointMarkerColor = $varvalue[1];
						break;
					case "gpxspeedchartlinewidth":
						if (is_numeric($varvalue[1])) {
							$this->gpxSpeedLineWidth = intval($varvalue[1]);
						}
						break;
					case "gpxspeedchartheight":
						if (is_numeric($varvalue[1])) {
							$this->gpxSpeedChartHeight = intval($varvalue[1]);
						}
						break;
					case "gpxheartratechartlinewidth":
						if (is_numeric($varvalue[1])) {
							$this->gpxHeartRateLineWidth = intval($varvalue[1]);
						}
						break;
					case "gpxheartbeatchartheight":
						if (is_numeric($varvalue[1])) {
							$this->gpxHeartRateChartHeight = intval($varvalue[1]);
						}
						break;
					case "gpxlineopacity":
						if (is_numeric($varvalue[1])) {
							$this->gpxLineOpacity = intval($varvalue[1]);
						}
						break;
					case "gpxdirectopenlink":
						$this->gpxDirectOpenWPLink = $varvalue[1];
						break;
					case "gpxview":
						$this->gpxView = $varvalue[1];
						break;
					case "maxlat":
						if (is_numeric($varvalue[1])) {
							$this->maxLat = doubleval($varvalue[1]);
							$this->manualZoom++;
						}
						break;
					case "maxlon":
						if (is_numeric($varvalue[1])) {
							$this->maxLon = doubleval($varvalue[1]);
							$this->manualZoom++;
						}
						break;
					case "minlat":
						if (is_numeric($varvalue[1])) {
							$this->minLat = doubleval($varvalue[1]);
							$this->manualZoom++;
						}
						break;
					case "minlon":
						if (is_numeric($varvalue[1])) {
							$this->minLon = doubleval($varvalue[1]);
							$this->manualZoom++;
						}
						break;
					case "zoom":
						if (is_numeric($varvalue[1])) {
							$this->zoom = intval($varvalue[1]);
						}
						break;
					case "deltazoom":
						if (is_numeric($varvalue[1])) {
							$this->deltazoom = intval($varvalue[1]);
						}
						break;
				}
			}
		}
	}
}

class nggFunctions {

	function isNggInstalled() {
		foreach (get_option('active_plugins') as $plugin) {
			if (strpos($plugin,"nggallery.php") !== false) {
				return true;
			}
		}
		return false;
	}

	function isExifInstalled() {
		include_once dirname(__FILE__).'/xmlgooglemaps_exif.php';
		return exif::isInstalled();
	}

	function getNggPics($galleries,$pics) {
		global $wpdb;
		include_once dirname(__FILE__).'/xmlgooglemaps_exif.php';
		$ret = array();
		$pictures = array();
		foreach ($galleries as $gallery) {
			$gallery = $wpdb->escape($gallery);
			$pictures = array_merge($pictures, $wpdb->get_results("SELECT t.*, tt.* FROM $wpdb->nggallery AS t INNER JOIN $wpdb->nggpictures AS tt ON t.gid=tt.galleryid WHERE t.gid = '$gallery' AND tt.exclude != 1"));
		}

		foreach ($pics as $pic) {
			$pic = $wpdb->escape($pic);
			$pictures = array_merge($pictures , $wpdb->get_results("SELECT t.*, tt.* FROM $wpdb->nggallery AS t INNER JOIN $wpdb->nggpictures AS tt ON t.gid=tt.galleryid WHERE tt.pid = '$pic' AND tt.exclude != 1"));
		}
		foreach ($pictures as $picrow) {
			$item = array();
			$thumb = $this->get_thumbnail_addition($picrow->path);
			$item["path"] = get_option('siteurl')."/".$picrow->path."/".$picrow->filename;
			$item["abspath"] = WINABSPATH."/".$picrow->path."/".$picrow->filename;
			$item["thumbpath"] = get_option('siteurl')."/".$picrow->path.$thumb.$picrow->filename;
			$item["description"] = html_entity_decode(stripslashes($picrow->description));
			$item["title"] = html_entity_decode(stripslashes($picrow->alttext));
			$item["galtitle"] = $picrow->title;
			$item["galdescription"] = html_entity_decode(stripslashes($picrow->galdesc));
			$exif = new exif($item["abspath"]);
			if ($exif->isValid) {
				$item["gpslat"] = $exif->getGPSLatitude();
				$item["gpslon"] = $exif->getGPSLongitude();
				$item["creation"] = $exif->getCreationDateTime();
				if (($item["gpslat"] != 0) || ($item["gpslon"] != 0)) {
					$ret[] = $item;
				}
			}
		}
		return $ret;
	}

	function get_thumbnail_addition($gallerypath) {
		$gallerypath = WINABSPATH.$gallerypath;
			
		if (!file_exists($gallerypath))
		return FALSE;
			
		if (is_dir($gallerypath."/thumbs")) {
			$thumbFolder 	= "/thumbs/";
			$thumbPrefix 	= "thumbs_";
			return $thumbFolder.$thumbPrefix;
		}
		// old mygallery check
		if (is_dir($gallerypath."/tumbs")) {
			$thumbFolder	= "/tumbs/";
			$thumbPrefix 	= "tmb_";
			return $thumbFolder.$thumbPrefix;
		}

		if (is_admin()) {
			if (!is_dir($gallerypath."/thumbs")) {
				if ( !wp_mkdir_p($gallerypath."/thumbs") )
				return "";
				$thumbFolder	= "/thumbs/";
				$thumbPrefix 	= "thumbs_";
				return $thumbFolder.$thumbPrefix;
			}
		}
		return "";
	}
}

class myFunctions {

	function getFileContent($url) {
		$filecontent = "";
		if (function_exists("curl_init")) {
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 3);
			$filecontent = curl_exec($ch);
			curl_close($ch);
			return $filecontent;
		} else {
			$url = myFunctions::tryGetLocalPath($url);
			if (!($fp = fopen($url, "r"))) {
				return false;
			}
			while ($data = fread($fp, 4096)) {
				$filecontent .= $data;
			}
			fclose($fp);
			return $filecontent;
		}
	}

	function tryGetLocalPath($url) {
		$root_path = ABSPATH;
		$root_url = get_option('siteurl')."/";

		$ret = str_replace($root_url,$root_path,$url);

		return $ret;
	}

	function longitude2Text($lon) {
		$lon = floatval($lon);
		if ($lon>=0) {$h="E";} else {$h="W"; $lon=-1*$lon;}
		$value1 = floor($lon);
		$lon = ($lon - $value1) * 60;
		$value2 = floor($lon);
		$lon = ($lon - $value2) * 60;
		$value3 = floor($lon);
		$lon = ($lon - $value3) * 100;
		$value4 = floor($lon);
		return $h." ".$value1."&deg; ".str_pad($value2,2,"0",STR_PAD_LEFT)."&apos; ".str_pad($value3,2,"0",STR_PAD_LEFT).".".str_pad($value4,2,"0",STR_PAD_LEFT)."&quot;";
	}

	function latitude2Text($lat) {
		$lat = floatval($lat);
		if ($lat>=0) {$h="N";} else {$h="S"; $lat=-1*$lat;}
		$value1 = floor($lat);
		$lat = ($lat - $value1) * 60;
		$value2 = floor($lat);
		$lat = ($lat - $value2) * 60;
		$value3 = floor($lat);
		$lat = ($lat - $value3) * 100;
		$value4 = floor($lat);
		return $h." ".$value1."&deg; ".str_pad($value2,2,"0",STR_PAD_LEFT)."&apos; ".str_pad($value3,2,"0",STR_PAD_LEFT).".".str_pad($value4,2,"0",STR_PAD_LEFT)."&quot;";
	}

	function elevation2Text($alt, $type) {
		switch ($params->measurement) {
			case "imperial":
			case "nautic_imperial":
				return round($alt/0.3048,0)." ft";
				break;
			case "nautic_metric":
			case "metric":
			default:
				return round($alt,0)." m";
				break;
		}
	}

	function seconds2Text($seconds) {
		$hours = floor($seconds / (60*60));
		$seconds -= $hours *(60*60);
		$minutes = floor($seconds / 60);
		$seconds -= $minutes*60;
		$seconds = floor($seconds);
		if ($hours != 0) {
			return  $hours."h ".str_pad($minutes,2,"0",STR_PAD_LEFT)."m ".str_pad($seconds,2,"0",STR_PAD_LEFT)."s";
		} else {
			if ($minutes != 0) {
				return $minutes."m ".str_pad($seconds,2,"0",STR_PAD_LEFT)."s";
			} else {
				return $seconds."s";
			}
		}
	}

	function getSpeedString($measurement,$scale,$distancekm,$timesec) {
		if ($timesec==0) {
			return "-";
		} else {
			return sprintf("%01.2f",myFunctions::getSpeed($measurement,$scale,$distancekm,$timesec))." ".myFunctions::getSpeedMeasurementString($measurement,$scale);
		}
	}
	
	function getDivision($v1, $v2, $round=0) {
		if ($v2==0) {
			return '-';
		} else {
			return round($v1 / $v2, $round);
		}
	}

	function getSpeedString2($measurement,$scale,$speed) {
		if (intval($speed)==0) {
			return "-";
		} else {
			return sprintf("%01.2f",$speed)." ".myFunctions::getSpeedMeasurementString($measurement,$scale);
		}
	}

	function getSpeedMeasurementString($measurement,$scale) {
		switch (strtolower($measurement.$scale)) {
			case "imperiallevel2":
				return "mph";
				break;
			case "imperiallevel1":
				return "fph";
				break;
			case "metriclevel1":
				return "m/s";
				break;
			case "nautic_metriclevel1":
			case "nautic_metriclevel2":
			case "nautic_imperiallevel1":
			case "nautic_imperiallevel2":
				return "kn";
				break;
			default:
				return "km/h";
				break;
		}
	}

	function getSpeed($measurement,$scale,$distancekm,$timesec)
	{
		if ($timesec==0) {
			return 0;
		} else {
			switch (strtolower($measurement.$scale)) {
				case "imperiallevel2":
					return ($distancekm/1.609344) / ($timesec/3600);
					break;
				case "imperiallevel1":
					return ($distancekm/0.3048) / ($timesec);
					break;
				case "metriclevel1":
					return ($distancekm*1000) / ($timesec);
					break;
				case "nautic_metriclevel1":
				case "nautic_metriclevel2":
				case "nautic_imperiallevel1":
				case "nautic_imperiallevel2":
					return ($distancekm/1.852216) / ($timesec/3600);
					break;
				default:
					return ($distancekm) / ($timesec/3600);
					break;
			}
		}
	}

	function distBetween2PointsKM($lat1, $lon1, $lat2, $lon2) {
		$lat1 = deg2rad($lat1);
		$lon1 = deg2rad($lon1);
		$lat2 = deg2rad($lat2);
		$lon2 = deg2rad($lon2);
		$ret = rad2deg(acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($lon2 - $lon1))) * 111.1206;
		if (is_nan($ret)) {
			$ret=0;
		}
		return $ret;
	}

	function xmlDate2DateTime($value) {
		$value = str_replace("Z","",$value);
		return strtotime($value);
	}

	function getJavascriptDecimalNumber($value,$rounding=3) {
		return number_format($value,$rounding,".","");
	}

	function colorName2Hex($name) {
		switch (strtolower($name)) {
			case "aliceblue": return "#F0F8FF"; break;
			case "antiquewhite": return "#FAEBD7"; break;
			case "aqua": return "#00FFFF"; break;
			case "aquamarine": return "#7FFFD4"; break;
			case "azure": return "#F0FFFF"; break;
			case "beige": return "#F5F5DC"; break;
			case "bisque": return "#FFE4C4"; break;
			case "black": return "#000000"; break;
			case "blanchedalmond": return "#FFEBCD"; break;
			case "blue": return "#0000FF"; break;
			case "blueviolet": return "#8A2BE2"; break;
			case "brown": return "#A52A2A"; break;
			case "burlywood": return "#DEB887"; break;
			case "cadetblue": return "#5F9EA0"; break;
			case "chartreuse": return "#7FFF00"; break;
			case "chocolate": return "#D2691E"; break;
			case "coral": return "#FF7F50"; break;
			case "cornflowerblue": return "#6495ED"; break;
			case "cornsilk": return "#FFF8DC"; break;
			case "crimson": return "#DC143C"; break;
			case "cyan": return "#00FFFF"; break;
			case "darkblue": return "#00008B"; break;
			case "darkcyan": return "#008B8B"; break;
			case "darkgoldenrod": return "#B8860B"; break;
			case "darkgray": return "#A9A9A9"; break;
			case "darkgrey": return "#A9A9A9"; break;
			case "darkgreen": return "#006400"; break;
			case "darkkhaki": return "#BDB76B"; break;
			case "darkmagenta": return "#8B008B"; break;
			case "darkolivegreen": return "#556B2F"; break;
			case "darkorange": return "#FF8C00"; break;
			case "darkorchid": return "#9932CC"; break;
			case "darkred": return "#8B0000"; break;
			case "darksalmon": return "#E9967A"; break;
			case "darkseagreen": return "#8FBC8F"; break;
			case "darkslateblue": return "#483D8B"; break;
			case "darkslategray": return "#2F4F4F"; break;
			case "darkslategrey": return "#2F4F4F"; break;
			case "darkturquoise": return "#00CED1"; break;
			case "darkviolet": return "#9400D3"; break;
			case "deeppink": return "#FF1493"; break;
			case "deepskyblue": return "#00BFFF"; break;
			case "dimgray": return "#696969"; break;
			case "dimgrey": return "#696969"; break;
			case "dodgerblue": return "#1E90FF"; break;
			case "firebrick": return "#B22222"; break;
			case "floralwhite": return "#FFFAF0"; break;
			case "forestgreen": return "#228B22"; break;
			case "fuchsia": return "#FF00FF"; break;
			case "gainsboro": return "#DCDCDC"; break;
			case "ghostwhite": return "#F8F8FF"; break;
			case "gold": return "#FFD700"; break;
			case "goldenrod": return "#DAA520"; break;
			case "gray": return "#808080"; break;
			case "grey": return "#808080"; break;
			case "green": return "#008000"; break;
			case "greenyellow": return "#ADFF2F"; break;
			case "honeydew": return "#F0FFF0"; break;
			case "hotpink": return "#FF69B4"; break;
			case "indianred ": return "#CD5C5C"; break;
			case "indigo ": return "#4B0082"; break;
			case "ivory": return "#FFFFF0"; break;
			case "khaki": return "#F0E68C"; break;
			case "lavender": return "#E6E6FA"; break;
			case "lavenderblush": return "#FFF0F5"; break;
			case "lawngreen": return "#7CFC00"; break;
			case "lemonchiffon": return "#FFFACD"; break;
			case "lightblue": return "#ADD8E6"; break;
			case "lightcoral": return "#F08080"; break;
			case "lightcyan": return "#E0FFFF"; break;
			case "lightgoldenrodyellow": return "#FAFAD2"; break;
			case "lightgray": return "#D3D3D3"; break;
			case "lightgrey": return "#D3D3D3"; break;
			case "lightgreen": return "#90EE90"; break;
			case "lightpink": return "#FFB6C1"; break;
			case "lightsalmon": return "#FFA07A"; break;
			case "lightseagreen": return "#20B2AA"; break;
			case "lightskyblue": return "#87CEFA"; break;
			case "lightslategray": return "#778899"; break;
			case "lightslategrey": return "#778899"; break;
			case "lightsteelblue": return "#B0C4DE"; break;
			case "lightyellow": return "#FFFFE0"; break;
			case "lime": return "#00FF00"; break;
			case "limegreen": return "#32CD32"; break;
			case "linen": return "#FAF0E6"; break;
			case "magenta": return "#FF00FF"; break;
			case "maroon": return "#800000"; break;
			case "mediumaquamarine": return "#66CDAA"; break;
			case "mediumblue": return "#0000CD"; break;
			case "mediumorchid": return "#BA55D3"; break;
			case "mediumpurple": return "#9370D8"; break;
			case "mediumseagreen": return "#3CB371"; break;
			case "mediumslateblue": return "#7B68EE"; break;
			case "mediumspringgreen": return "#00FA9A"; break;
			case "mediumturquoise": return "#48D1CC"; break;
			case "mediumvioletred": return "#C71585"; break;
			case "midnightblue": return "#191970"; break;
			case "mintcream": return "#F5FFFA"; break;
			case "mistyrose": return "#FFE4E1"; break;
			case "moccasin": return "#FFE4B5"; break;
			case "navajowhite": return "#FFDEAD"; break;
			case "navy": return "#000080"; break;
			case "oldlace": return "#FDF5E6"; break;
			case "olive": return "#808000"; break;
			case "olivedrab": return "#6B8E23"; break;
			case "orange": return "#FFA500"; break;
			case "orangered": return "#FF4500"; break;
			case "orchid": return "#DA70D6"; break;
			case "palegoldenrod": return "#EEE8AA"; break;
			case "palegreen": return "#98FB98"; break;
			case "paleturquoise": return "#AFEEEE"; break;
			case "palevioletred": return "#D87093"; break;
			case "papayawhip": return "#FFEFD5"; break;
			case "peachpuff": return "#FFDAB9"; break;
			case "peru": return "#CD853F"; break;
			case "pink": return "#FFC0CB"; break;
			case "plum": return "#DDA0DD"; break;
			case "powderblue": return "#B0E0E6"; break;
			case "purple": return "#800080"; break;
			case "red": return "#FF0000"; break;
			case "rosybrown": return "#BC8F8F"; break;
			case "royalblue": return "#4169E1"; break;
			case "saddlebrown": return "#8B4513"; break;
			case "salmon": return "#FA8072"; break;
			case "sandybrown": return "#F4A460"; break;
			case "seagreen": return "#2E8B57"; break;
			case "seashell": return "#FFF5EE"; break;
			case "sienna": return "#A0522D"; break;
			case "silver": return "#C0C0C0"; break;
			case "skyblue": return "#87CEEB"; break;
			case "slateblue": return "#6A5ACD"; break;
			case "slategray": return "#708090"; break;
			case "slategrey": return "#708090"; break;
			case "snow": return "#FFFAFA"; break;
			case "springgreen": return "#00FF7F"; break;
			case "steelblue": return "#4682B4"; break;
			case "tan": return "#D2B48C"; break;
			case "teal": return "#008080"; break;
			case "thistle": return "#D8BFD8"; break;
			case "tomato": return "#FF6347"; break;
			case "turquoise": return "#40E0D0"; break;
			case "violet": return "#EE82EE"; break;
			case "wheat": return "#F5DEB3"; break;
			case "white": return "#FFFFFF"; break;
			case "whitesmoke": return "#F5F5F5"; break;
			case "yellow": return "#FFFF00"; break;
			case "yellowgreen": return "#9ACD32"; break;
			default: return $name; break;
		}
	}

	function xml2array($contents, $get_attributes=1) {
		if(!$contents) return array();
			
		if(!function_exists('xml_parser_create')) {
			return array();
		}
		//Get the XML parser of PHP - PHP must have this module for the parser to work
		$parser = xml_parser_create();
		xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, 0 );
		xml_parser_set_option( $parser, XML_OPTION_SKIP_WHITE, 1 );
		xml_parse_into_struct( $parser, $contents, $xml_values );
		xml_parser_free( $parser );

		if(!$xml_values) return;//Hmm...

		//Initializations
		$xml_array = array();
		$parents = array();
		$opened_tags = array();
		$arr = array();

		$current = &$xml_array;

		//Go through the tags.
		foreach($xml_values as $data) {
			unset($attributes,$value);//Remove existing values, or there will be trouble

			//This command will extract these variables into the foreach scope
			// tag(string), type(string), level(int), attributes(array).
			extract($data);//We could use the array by itself, but this cooler.
			$tag = strtolower($tag);

			$result = '';
			if($get_attributes) {//The second argument of the function decides this.
				$result = array();
				if(isset($value)) $result['value'] = $value;

				//Set the attributes too.
				if(isset($attributes)) {
					foreach($attributes as $attr => $val) {
						if($get_attributes == 1) $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
						/**  :TODO: should we change the key name to '_attr'? Someone may use the tagname 'attr'. Same goes for 'value' too */
					}
				}
			} elseif(isset($value)) {
				$result = $value;
			}

			//See tag status and do the needed.
			if($type == "open") {//The starting of the tag '<tag>'
				$parent[$level-1] = &$current;

				if(!is_array($current) or (!in_array($tag, array_keys($current)))) { //Insert New tag
					$current[$tag] = $result;
					$current = &$current[$tag];

				} else { //There was another element with the same tag name
					if(isset($current[$tag][0])) {
						array_push($current[$tag], $result);
					} else {
						$current[$tag] = array($current[$tag],$result);
					}
					$last = count($current[$tag]) - 1;
					$current = &$current[$tag][$last];
				}

			} elseif($type == "complete") { //Tags that ends in 1 line '<tag />'
				//See if the key is already taken.
				if(!isset($current[$tag])) { //New Key
					$current[$tag] = $result;

				} else { //If taken, put all things inside a list(array)
					if((is_array($current[$tag]) and $get_attributes == 0)//If it is already an array...
					or (isset($current[$tag][0]) and is_array($current[$tag][0]) and $get_attributes == 1)) {
						array_push($current[$tag],$result); // ...push the new element into that array.
					} else { //If it is not an array...
						$current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
					}
				}

			} elseif($type == 'close') { //End of tag '</tag>'
				$current = &$parent[$level-1];
			}
		}
			
		return($xml_array);
	}

}

class dbFunctions {		

	function install() {
		global $wpdb;

		$charset_collate = '';
		if ( $wpdb->has_cap( 'collation' ) ) {
			if ( ! empty($wpdb->charset) )
			$charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
			if ( ! empty($wpdb->collate) )
			$charset_collate .= " COLLATE $wpdb->collate";
		}

		if (!dbFunctions::tableExists($wpdb->xmlgooglemapsdb)) {
			$create_sql = "CREATE TABLE $wpdb->xmlgooglemapsdb (".
				"xml_id INT(11) NOT NULL auto_increment,".
				"xml_path TEXT NOT NULL ,".			
				"PRIMARY KEY (xml_id)) $charset_collate;";
			$wpdb->query($create_sql);
		}
		if (!dbFunctions::columnExists($wpdb->xmlgooglemapsdb,"xml_varstring")) {
			$column_sql = "ALTER TABLE $wpdb->xmlgooglemapsdb ADD COLUMN xml_varstring TEXT NOT NULL;";
			$wpdb->query($column_sql);
		}
		if (dbFunctions::columnExists($wpdb->xmlgooglemapsdb,"xml_path_resolved")) {
			$column_sql = "ALTER TABLE $wpdb->xmlgooglemapsdb DROP xml_path_resolved;";
			$wpdb->query($column_sql);
		}
		if (!dbFunctions::tableExists($wpdb->xmlgooglemapsdbcache)) {
			$create_sql = "CREATE TABLE $wpdb->xmlgooglemapsdbcache (".
				"xml_id INT(11) NOT NULL,".
				"xml_cache_key VARCHAR(20) NOT NULL ,".
				"xml_cache_lastupdated DATETIME NOT NULL ,".
				"xml_cache_content LONGTEXT NOT NULL ,".
				"PRIMARY KEY (xml_id, xml_cache_key)) $charset_collate;";
			$wpdb->query($create_sql);
		}
		if (strtolower(dbFunctions::columnType($wpdb->xmlgooglemapsdbcache,"xml_cache_content")) == "text") {
			$column_sql = "ALTER TABLE $wpdb->xmlgooglemapsdbcache CHANGE xml_cache_content xml_cache_content LONGTEXT NOT NULL";
			$wpdb->query($column_sql);
			dbFunctions::clearAllCache();
		}		
	}

	function tableExists($tablename) {
		global $wpdb;
		foreach ($wpdb->get_col("SHOW TABLES",0) as $table ) {
			if ($table == $tablename) {
				return true;
			}
		}
		return false;
	}

	function columnExists($tablename, $columnname) {
		global $wpdb;
		$col1 = $wpdb->get_col("DESC $tablename", 0);
		foreach ($col1 as $column ) {
			if ($column == $columnname) {
				return true;
			}
		}
		return false;
	}
	
	function columnType($tablename, $columnname) {
		global $wpdb;
		$rows = $wpdb->get_results("DESC $tablename");
		foreach ($rows as $key => $value) {
			if ($value->Field == $columnname) {
				return $value->Type;
			}
		}
		return "";		
	}

	function clearCache($id, $key, $cacheDuration) {
		global $wpdb;
		if ($cacheDuration==-1) {
			$wpdb->query($wpdb->prepare("DELETE FROM $wpdb->xmlgooglemapsdbcache WHERE xml_id=%d AND xml_cache_key=%s",$id,$key));			
		} else {
			if ($cacheDuration>0) {
				$expirationTime = date('Y-m-d H:i:s', time() - 60 * $cacheDuration);
				$wpdb->query($wpdb->prepare("DELETE FROM $wpdb->xmlgooglemapsdbcache WHERE xml_id=%d AND xml_cache_key=%s AND xml_cache_lastupdated<%s",$id,$key,$expirationTime));
			}
		}
	}
	
	function clearAllCache() {
		global $wpdb;
		$wpdb->query($wpdb->prepare("DELETE FROM $wpdb->xmlgooglemapsdbcache"));			
	}	
	
	function hasCache($id, $key, $cacheDuration) {
		global $wpdb;
		dbFunctions::clearCache($id,$key,$cacheDuration);		
		$ret = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $wpdb->xmlgooglemapsdbcache WHERE xml_id=%d AND xml_cache_key=%s", $id, $key));
		return intval($ret)>0;	
	}
	
	function getCacheCount() {
		global $wpdb;		
		$ret = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $wpdb->xmlgooglemapsdbcache", $id, $key));
		return intval($ret);			
	}
	
	function getCache($id, $key, $cacheDuration) {
		global $wpdb;
		if (dbFunctions::hasCache($id,$key,$cacheDuration)) {	
			$ret = $wpdb->get_var($wpdb->prepare("SELECT xml_cache_content FROM $wpdb->xmlgooglemapsdbcache WHERE xml_id=%d AND xml_cache_key=%s", $id, $key));
			return $ret;	
		} else {
			return false;
		} 
	}
	
	function setCache($id, $key, $value) {
		global $wpdb;
		dbFunctions::clearCache($id,$key,-1);
		$now = date('Y-m-d H:i:s', time());	
		$wpdb->query($wpdb->prepare("INSERT INTO $wpdb->xmlgooglemapsdbcache (xml_id, xml_cache_key, xml_cache_lastupdated, xml_cache_content) VALUES (%d, %s, %s, %s)", $id, $key, $now, $value));
	}

	function getId($path, $varstring) {
		global $wpdb;
		// Check IP From IP Logging Database
		$ret = $wpdb->get_var($wpdb->prepare("SELECT xml_id FROM $wpdb->xmlgooglemapsdb WHERE xml_path = %s AND xml_varstring = %s",$path,$varstring));
		if ($ret == 0) {
			$wpdb->query($wpdb->prepare("INSERT INTO $wpdb->xmlgooglemapsdb (xml_path, xml_varstring) VALUES (%s,%s)",$path,$varstring));
			$ret = dbFunctions::getId($path, $varstring);
		}
		return intval($ret);
	}

	function getPath($id) {
		global $wpdb;
		// Check IP From IP Logging Database
		$ret = $wpdb->get_var($wpdb->prepare("SELECT xml_path FROM $wpdb->xmlgooglemapsdb WHERE xml_id = %d",$id));
		return $ret;
	}


	function getVarString($id) {
		global $wpdb;
		// Check IP From IP Logging Database
		$ret = $wpdb->get_var($wpdb->prepare("SELECT xml_varstring FROM $wpdb->xmlgooglemapsdb WHERE xml_id = %d",$id));
		return $ret;
	}

}
?>